package it.blueocean.acanto.platform.aop.logging;

import java.lang.reflect.Method;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;

public class AuditingLoggerInterceptor implements MethodBeforeAdvice, AfterReturningAdvice, MethodInterceptor
{
	private static Logger logger = null;

	public AuditingLoggerInterceptor()
	{
	}

	public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable
	{
		logger = LoggerFactory.getLogger(arg2.getClass());

		logger.info("Beginning method: " + arg0.getName());
	}

	public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable
	{
		logger = LoggerFactory.getLogger(arg3.getClass());

		logger.info("Ending method: " + arg1.getName());
	}

	public Object invoke(MethodInvocation invocation) throws Throwable
	{
		logger = LoggerFactory.getLogger(invocation.getClass());

		StringBuilder logLine = new StringBuilder();
		logLine.append("Calling: ");
		Method m = invocation.getMethod();
		logLine.append(m.getDeclaringClass().getName()).append(".").append(m.getName()).append("(");
		Object[] params = invocation.getArguments();

		if(params != null && params.length > 0)
		{
			int counter = 0;

			for (Object param : params)
			{
				logLine.append(param);

				counter++;

				if(counter < params.length)
				{
					logLine.append(", ");
				}
			}
		}

		logLine.append(")");

		logger.debug(logLine.toString());

		Object returnValue = invocation.proceed();

		StringBuilder logReturnLine = new StringBuilder();
		logReturnLine.append("Returned: ").append(returnValue);

		logger.debug(logReturnLine.toString());

		return returnValue;
	}

}